package com.upb.webserver.user;

import com.fasterxml.jackson.core.type.TypeReference;
import com.upb.webserver.account.AccountService;
import com.upb.webserver.application.ApplicationManager;
import com.upb.webserver.common.enums.ChainTypeEnum;
import com.upb.webserver.common.pojo.account.AccountCommon;
import com.upb.webserver.common.pojo.base.BasePageResponse;
import com.upb.webserver.common.pojo.base.BaseResponse;
import com.upb.webserver.common.pojo.user.ReqAddUserVO;
import com.upb.webserver.common.pojo.user.RspUserVO;
import com.upb.webserver.common.returncode.ConstantCode;
import com.upb.webserver.common.tools.JsonUtils;
import com.upb.webserver.dao.entity.TbApplication;
import com.upb.webserver.org.OrgManager;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * key user.
 */
@Log4j2
@RestController
@RequestMapping("user")
public class UserController {
    @Autowired
    private ApplicationManager applicationManager;
    @Autowired
    private OrgManager orgManager;
    @Autowired
    private UserService userService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private UserServiceFactory userServiceFactory;

    /**
     * create new user.
     *
     * @param param
     * @param result
     * @return
     */
    @PostMapping
    public BaseResponse createNewUser(@RequestBody @Valid ReqAddUserVO param, BindingResult result) {
        log.info("start exec method [createNewUser]. param:{}", JsonUtils.objToString(param));
        //check org
        if (null != param.getOrgId())
            orgManager.verifyOrgId(param.getOrgId());

        //check appId
        TbApplication application = applicationManager.verifyApplicationId(param.getApplicationId());
        //create
        BaseResponse baseResponse = userServiceFactory.getUserServiceByChainType(application.getChainType()).createNewUser(param);

        log.info("success exec method [createNewUser].");
        return baseResponse;
    }

    /**
     * @param pageNumber
     * @param pageSize
     * @param applicationId
     * @param request
     * @return
     */
    @GetMapping(value = "list")
    public BasePageResponse queryUserByPage(@RequestParam("pageNumber") Integer pageNumber,
                                            @RequestParam("pageSize") Integer pageSize,
                                            @RequestParam(value = "applicationId") Integer applicationId,
                                            HttpServletRequest request) {
        log.info("start exec method [queryUserByPage]. pageNumber:{} pageSize:{} applicationId", pageNumber, pageSize, applicationId);
        //check applicationId
        TbApplication application = applicationManager.verifyApplicationId(applicationId);

        //query
        BasePageResponse baseResponse = userServiceFactory.getUserServiceByChainType(application.getChainType()).listUserByApplication(applicationId, pageNumber, pageSize);

        log.info("success exec method [queryUserByPage].");
        log.debug("success exec method [queryUserByPage]. result:{}", JsonUtils.objToString(baseResponse));
        return baseResponse;
    }


    /**
     * @param pageNumber
     * @param pageSize
     * @param chainId
     * @param applicationId
     * @param request
     * @return
     */
    @GetMapping(value = "user-page")
    public BasePageResponse queryUserByPage(@RequestParam(value = "pageNumber", required = false, defaultValue = "1") Integer pageNumber,
                                            @RequestParam(value = "pageSize", required = false, defaultValue = "50") Integer pageSize,
                                            @RequestParam(value = "chainId", required = false) Integer chainId,
                                            @RequestParam(value = "applicationId", required = false) Integer applicationId,
                                            HttpServletRequest request) {
        log.info("start exec method [queryUserByPage]. pageNumber:{} pageSize:{} chainId:{} chainType:{} applicationId:{}", pageNumber, pageSize, chainId, applicationId);
        AccountCommon accountCommon = accountService.getAccountCommon(request);
        BasePageResponse fiscoResult = null;

        try {
            fiscoResult = userService.queryByPage(accountCommon.getPlatform(), accountCommon.getId(), pageNumber, pageSize, chainId, ChainTypeEnum.FISCO.getId(), applicationId);
        } catch (Exception ex) {
            log.info("get use failed fiscoResult --> {}", JsonUtils.objToString(ex));
        }


        BasePageResponse basePageResponse = new BasePageResponse(ConstantCode.SUCCESS);
        basePageResponse.setTotalCount((fiscoResult == null ? 0 : fiscoResult.getTotalCount()));
        List<RspUserVO> rspUserList = new ArrayList<>();
        if (fiscoResult != null) {
            List<RspUserVO> userFiscoList = JsonUtils.stringToObj(JsonUtils.objToString(fiscoResult.getData()),
                    new TypeReference<List<RspUserVO>>() {
                    });
            if (CollectionUtils.isNotEmpty(userFiscoList)) {
                rspUserList.addAll((ArrayList) fiscoResult.getData());
            }
        }

        basePageResponse.setData(rspUserList);

        log.info("success exec method [queryUserByPage].");
        log.debug("success exec method [queryUserByPage]. result:{}", JsonUtils.objToString(basePageResponse));
        return basePageResponse;
    }

}
